using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using UnityEngine;


namespace GameBaseFramework.Extension
{

    public static class GraphicExtensions
    {
        /// <summary>
        /// 直角坐标系转柱坐标系
        /// </summary>
        /// <returns></returns>
        public static Vector3 FromCarteToCylin(this Vector3 self)
        {
            var x = self.x;
            var y = self.z;
            var z = self.y;
            var r = Mathf.Sqrt(x * x + y * y + z * z);
            if (r == 0) return Vector3.zero;
            var fi = Mathf.Atan(y / x);
            return new Vector3(r, fi, z);
        }

        /// <summary>
        /// 柱坐标系转直角坐标系
        /// </summary>
        /// <returns></returns>
        public static Vector3 FromCylinToCarte(this Vector3 self)
        {
            var r = self.x;
            var fi = self.y;
            var z = self.z;
            var l = Mathf.Sqrt(r * r - z * z);

            return new Vector3(l * Mathf.Cos(fi), z, l * Mathf.Sin(fi));
        }

        /// <summary>
        /// 直角坐标系转球坐标系
        /// </summary>
        /// <returns></returns>
        public static Vector3 FromCarteToSphere(this Vector3 self)
        {
            var x = self.x;
            var y = self.z;
            var z = self.y;
            var r = Mathf.Sqrt(x * x + y * y + z * z);
            if (r == 0) return Vector3.zero;
            var sigma = Mathf.Acos(z / r);
            var fi = Mathf.Atan(y / x);
            return new Vector3(r, sigma, fi);
        }

        /// <summary>
        /// 球坐标系转直角坐标系
        /// </summary>
        /// <returns></returns>
        public static Vector3 FromSphereToCarte(this Vector3 self)
        {
            var r = self.x;
            var sigma = self.y;
            var fi = self.z;

            return new Vector3(r * Mathf.Sin(sigma) * Mathf.Cos(fi), r * Mathf.Cos(sigma), r * Mathf.Sin(sigma) * Mathf.Sin(fi));
        }

        /// <summary>
        /// 使用旋转矩阵旋转角度
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static Vector3 RotateY(this Vector3 self, float angle)
        {
            angle = angle * Mathf.Deg2Rad;
            return new Vector3
            {
                x = Mathf.Cos(angle) * self.x + Mathf.Sin(angle) * self.z,
                y = self.y,
                z = - Mathf.Sin(angle) * self.x + Mathf.Cos(angle) * self.z
            };
        }

        /// <summary>
        /// 使用旋转矩阵旋转角度
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static Vector3 RotateX(this Vector3 self, float angle)
        {
            return new Vector3
            {
                x = self.x,
                y = Mathf.Cos(angle) * self.y + Mathf.Sin(angle) * self.z,
                z = - Mathf.Sin(angle) * self.y + Mathf.Cos(angle) * self.z,
            };
        }

        /// <summary>
        /// 使用旋转矩阵旋转角度
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static Vector3 RotateZ(this Vector3 self, float angle)
        {
            return new Vector3
            {
                x = Mathf.Cos(angle) * self.x + Mathf.Sin(angle) * self.y,
                y = -Mathf.Sin(angle) * self.x + Mathf.Cos(angle) * self.y,
                z = self.z,
            };
        }

        /// <summary>
        /// 求两个向量绕轴axis 的角度
        /// </summary>
        /// <param name="dirA"></param>
        /// <param name="dirB"></param>
        /// <param name="axis"></param>
        public static float AngleAroundAxis(this Vector3 dirA, Vector3 dirB, Vector3 axis)
        {
            dirA = dirA - Vector3.Project(dirA, axis);

            dirB = dirB - Vector3.Project(dirB, axis);

            float angle = Vector3.Angle(dirA, dirB);

            return angle * (Vector3.Dot(axis, Vector3.Cross(dirA, dirB)) < 0 ? -1 : 1);
        }
    }
}
